Die einfachsten Wege, HTML Includes zu handhaben

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es ist für mich extrem überraschend, dass HTML nie eine Möglichkeit hatte, andere HTML-Dateien darin einzubinden. Auch scheint nichts am Horizont zu sein, das dies adressiert. Ich spreche von geradlinigen Includes, wie das Nehmen eines HTML-Abschnitts und das Einfügen direkt in einen anderen. Zum Beispiel der Anwendungsfall für einen Großteil des gesamten Internets, ein eingebundener Header und Footer für alle Seiten

...
<body>
   <include src="./header.html"></include>

   Content

   <include src="./footer.html"></include>
</body>
...

Das ist übrigens nicht real. Ich wünschte nur, es wäre es.

Die Leute greifen schon ewig auf andere Sprachen zurück, um dieses Problem für sich zu lösen. Es ist sozusagen HTML-Preprocessing. Lange bevor wir unser CSS vorverarbeiten, haben wir Werkzeuge zur Manipulation unseres HTML verwendet. Und das tun wir immer noch, denn die Idee von Includes ist auf so ziemlich jeder Website der Welt nützlich.

PHP verwenden

Kannst du stattdessen PHP verwenden?

...
<body>
   <?php include "./header.html" ?>

   Content

   <?php include "./footer.html" ?>
</body>
...

Dies wird den Include auf Serverebene durchführen, sodass die Anfrage auf Dateisystemebene auf dem Server erfolgt. Das sollte also weitaus schneller sein als eine clientseitige Lösung.

Gulp verwenden

Was ist noch schneller als ein serverseitiger Include? Wenn der Include vorverarbeitet wird, bevor er überhaupt auf dem Server ist. Gulp hat eine Vielzahl von Prozessoren, die das tun können. Einer davon ist gulp-file-include.

Das würde so aussehen

...
<body>
   @@include('./header.html')

   Content

   @@include('./footer.html')
</body>
...

Und du würdest es so verarbeiten:

var fileinclude = require('gulp-file-include'),
  gulp = require('gulp');
 
gulp.task('fileinclude', function() {
  gulp.src(['index.html'])
    .pipe(fileinclude({
      prefix: '@@',
      basepath: '@file'
    }))
    .pipe(gulp.dest('./'));
});

Dieses spezielle Plugin scheint schicke Funktionen zu haben, bei denen du Variablen an die Includes übergeben kannst, was es ermöglicht, kleine datengesteuerte Komponenten zu erstellen.

Grunt verwenden

Das macht das grunt-bake Plugin. Du würdest Grunt so konfigurieren, dass es dein HTML verarbeitet

grunt.initConfig({
    bake: {
        your_target: {
            files: {
                "dist/index.html": "app/index.html",
            }
        }
    }
});

Dann kann dein HTML diese spezielle Syntax für Includes verwenden

...
<body>
   <!--(bake header.html)-->

   Content

   <!--(bake footer.html)-->
</body>
...

Handlebars verwenden

Handlebars hat Partials.

Du registrierst sie

Handlebars.registerPartial('myPartial', '{{name}}')

Dann verwendest du sie

{{> myPartial }}

Es gibt auch schicke Funktionen, die Auswertung und Datenübergabe ermöglichen. Du brauchst aber immer noch einen Prozessor, um es auszuführen, wahrscheinlich etwas wie gulp-handlebars.

Apropos Vorlagensprachen, die geschweifte Klammern verwenden… Mustache haben sie auch.

Pug verwenden

Pug ist ein HTML-Präprozessor, der eine ganz neue Syntax für HTML hat, die etwas kürzer ist. Es hat aber Includes.

...
body
   include ./header.html"

   p Content

   include ./footer.html"

   ...

Dann führst du es mit etwas wie gulp-pug aus.

Nunjucks verwenden

Ich liebe Nunjucks! Nunjucks hat Includes. Das würdest du so machen:

...
<body>
   {% include "./header.html" %}

   Content

   {% include "./footer.html" %}
</body>
...

Wenn du das in eine Datei namens index.njk packst, könntest du es mit einem einfachen Node-Skript in index.html so verarbeiten:

const nunjucks = require("nunjucks");
const fs = require("fs");

fs.writeFile("index.html", nunjucks.render("index.njk"), function(err, data) {
  if (err) console.log(err);
  console.log("Compiled the Nunjucks, captain.");
});

Oder mit etwas wie gulp-nunjucks verarbeiten.

11ty hat Nunjucks integriert, zusammen mit vielen der anderen genannten. Könnte gut für dich sein, wenn du tatsächlich eine kleine Website baust.

AJAX verwenden

Angenommen, du hättest…

<body>
  
  <header></header>
  
  Content.
  
  <footer></footer>

</body>

Du könntest die Inhalte für Header und Footer aus entsprechenden Dateien abrufen und die Inhalte einfügen.

fetch("./header.html")
  .then(response => {
    return response.text()
  })
  .then(data => {
    document.querySelector("header").innerHTML = data;
  });

fetch("./footer.html")
  .then(response => {
    return response.text()
  })
  .then(data => {
    document.querySelector("footer").innerHTML = data;
  });

Apropos JavaScript… Wenn du deine Website mit einem JavaScript-Framework jeglicher Art baust, ist der Aufbau über Komponenten eigentlich das Hauptthema, und das Aufteilen von Teilen, die du in anderen Dateien einbinden möchtest, sollte kein Problem sein. Eine Art von import Header from "./header.js"; und <Header /> wäre das, was du im React-Bereich tun würdest.

IFrames verwenden

Du könntest das tun:

<body>
  
  <iframe src="./header.html"></iframe>
  
  Content.
  
  <iframe src="./footer.html"></iframe>
  
</body>

Aber der Inhalt dieser iframes teilt sich nicht den gleichen DOM, daher ist es etwas seltsam, ganz zu schweigen von langsam und umständlich zu stylen (da iframes die Höhen ihrer Inhalte nicht kennen).

Scott Jehl hat eine coole Idee dokumentiert: Du kannst den iframe den Inhalt seiner selbst auf die Elterseite injizieren lassen und sich dann entfernen.

<body>
  
  <iframe src="header.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
  
  Content.
  
  <iframe src="footer.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
  
</body>

Kolya Korruptis schrieb mit dieser Anpassung, die mehr als das erste Kind des Körpers einbeziehen wird, falls Ihre HTML-Datei das hat

<iframe src="included.html" onload="this.insertAdjacentHTML('afterend', (this.contentDocument.body||this.contentDocument).innerHTML);this.remove()"></iframe>

Jekyll verwenden

Jekyll ist ein Ruby-basierter statischer Site-Generator mit Includes. Du behältst deine Includes im /_includes/ Ordner, dann

<body>
  {% include header.html %}
  
  Content.

  {% include footer.html %}
</body>

Jekyll ist ein großer, daher hebe ich ihn hier hervor, aber es gibt eine Menge statischer Site-Generatoren und ich würde wetten, dass jeder von ihnen Includes kann.

Sergey verwenden

OK, ich nenne noch einen SSG nennenswert, weil er neu und super fokussiert ist. Sergey hat ein Web-Komponenten-Stil-Format

<body>
  <sergey-import src="header" />

  Content.

  <sergey-import src="footer" />
</body>

Du würdest die Dateien header.html und footer.html benennen und sie in /includes/ legen und dann wird eine Build mit den verarbeiteten Includes erstellt, wenn du das npm-Skript ausführst, das sie dir vorgeben.

Apache SSI verwenden

Apache, ein superduper gängiger Webserver, kann Includes. Das machst du so:

<body>
		
  <!--#include file="./header.html" -->
  
  Content
  
  <!--#include file="./footer.html" -->
  
</body>

Aber du brauchst die richtige Apache-Konfiguration, um Dinge zuzulassen. Ich habe mein Bestes getan, um eine funktionierende Demo zu erstellen, hatte aber wenig Erfolg.

Ich habe versucht, .htaccess in einem Ordner auf einem Apache-Server zu verwenden und die richtigen Dinge einzuschalten

Options +Includes

AddType text/html .html
AddOutputFilter INCLUDES .html

Ich bin sicher, es gibt einen Weg, es zum Laufen zu bringen, und wenn du es schaffst, ist es irgendwie nett, dass es keine zusätzlichen Abhängigkeiten braucht.

CodeKit verwenden

Nur für Mac, aber CodeKit hat eine spezielle Sprache namens Kit, die es verarbeitet, und deren Zweck zu 90% HTML-Includes sind. Es verwendet spezielle HTML-Kommentare

...
<body>
   <!-- @import "./header.html" -->

   Content

   <!-- @import "./footer.html" -->
</body>
...

Dreamweaver verwenden

Lol, kleiner Scherz. Aber es ist wirklich eine SacheDWTs, Baby.

Heiliger Bimbam

Das sind viele Wege, oder?

Wie ich oben sagte, ist es für mich sehr überraschend, dass HTML dies nicht direkt adressiert hat. Nicht, dass ich denke, es wäre eine großartige Idee für die Performance, <include>-Anweisungen zu haben, die Netzwerkanfragen über unseren gesamten Code auslösen, aber es scheint im Einklang mit der Plattform zu sein. Das direkte Importieren von ES6-Imports ohne Bündelung ist auch nicht immer eine gute Idee, aber wir haben sie. CSS innerhalb von CSS zu importieren ist auch nicht immer eine gute Idee, aber wir haben es. Wenn die Plattform eine native Syntax hätte, würden sich vielleicht andere Werkzeuge daran orientieren, ähnlich wie JavaScript-Bundler das ES6-Importformat unterstützen.