Eine Jekyll-Website erstellen – Teil 3 von 3: Ein kommentarsystem mit Firebase erstellen

Avatar of Mike Neumegen
Mike Neumegen am

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

Der folgende Beitrag ist ein Gastbeitrag von Mike Neumegen von CloudCannon. Dieser letzte Beitrag handelt davon, einer Jekyll-Website eine Funktionalität hinzuzufügen, die sonst nicht möglich ist: Kommentare. Das liegt daran, dass Jekyll keine Backend-Komponente hat, in der Kommentare gespeichert werden können. Aber das brauchen wir nicht einmal, wenn wir es komplett über das Frontend mit Firebase machen!

Artikelserie

  1. Eine statische Website in Jekyll konvertieren
  2. Ein Jekyll-CMS mit CloudCannon hinzufügen
  3. Ein kommentarsystem mit Firebase erstellen (Sie sind hier!)

In dieser Reihe bauen wir eine Website mit einem Blog und einem Content-Management-System für Coffee Cafe, ein fiktives Café. Dieser letzte Beitrag handelt vom Erstellen eines benutzerdefinierten kommentarsystems mit Firebase.

Benutzerdefinierte Lösungen bieten mehr Kontrolle über Design, Funktionalität und Daten als fertige Lösungen wie Disqus und Facebook Comments.

Was ist Firebase?

Firebase ist ein skalierbares Echtzeit-Backend. Es ermöglicht Entwicklern, Anwendungen mit Authentifizierung und persistenten Daten für statische Websites zu erstellen.

Wir werden unsere Blog-Kommentare in Firebase speichern und abrufen, wenn jemand einen Blog-Beitrag aufruft.

Registrieren

Registrieren Sie sich zunächst für ein Firebase-Konto.

Nach der Registrierung erstellen Sie eine neue App für die Blog-Kommentare und notieren Sie die **App-URL** für später.

Setup

Wir benötigen eine Reihe von JavaScript-Bibliotheken, um das kommentarsystem auszuführen. Firebase speichert und ruft Kommentare ab, jQuery fügt Elemente zur Seite hinzu, Moment formatiert Daten und blueimp-md5 generiert MD5s. `/js/blog.js` enthält den benutzerdefinierten Anwendungscode für das kommentarsystem.

Fügen Sie die folgenden Skripte oberhalb von </body> in `_layouts/default.html` ein (oder führen Sie den Build-Prozess / die Konkatenation durch, die Sie normalerweise verwenden)

<script src="https://cdn.firebase.com/js/client/2.2.1/firebase.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.1.0/js/md5.js"></script>
<script src="/js/blog.js"></script>

Firebase-Übersicht

Wenn ein Besucher einen Blog-Beitrag aufruft, rufen wir alle relevanten Kommentare von Firebase ab.

Besucher posten Kommentare mit einem Namen, einer E-Mail-Adresse und einer Nachricht. Wir nehmen diese Informationen, fügen einen Zeitstempel und die aktuelle Seite hinzu und speichern sie dann in Firebase.

In Firebase werden Daten als JSON-Objekte gespeichert. Die Kommentare werden als Array von Objekten für jeden Blog-Beitrag gespeichert.

{
  "/tutorial/2016/01/02/title-tag.html": [
    {
      "name": "Bill",
      "email": "[email protected]",
      "message": "Hi there, nice blog!",
      "timestamp": 1452042357209
    },
    {
      "name": "Bob",
      "email": "[email protected]",
      "message": "Wow look at this blog.",
      "timestamp": 145204235846
    }
  ],
  "/announcement/2016/01/01/latest-seo-trends.html": [
    {
      "name": "Steve",
      "email": "[email protected]",
      "message": "First post!",
      "timestamp": 1452043267245
    }
  ]
}

Implementierung

Firebase-Referenzen bieten Lese- und Schreibzugriff auf die Datenbank. Fügen Sie eine Referenz zur Datenbank in `/js/blog.js` hinzu.

var ref = new Firebase("https://<YOUR-APP-ID>.firebaseio.com/");

ref gibt uns Zugriff auf die Wurzel der Datenbank. Wir können eine Referenz auf einen Blog-Beitrag mit ref.child("<PFAD-ZUM-BLOG-BEITRAG>") erhalten.

Kommentare speichern

Der Pfad ist eine großartige Möglichkeit, einen Blog-Beitrag zu identifizieren, aber Firebase unterstützt keine Zeichen wie ein kaufmännisches Und im Schlüsselnamen. Um dieses Problem zu lösen, fügen Sie eine Funktion hinzu, um nicht unterstützte Zeichen zu ersetzen.

function slugify(text) {
  return text.toString().toLowerCase().trim()
    .replace(/&/g, '-and-')
    .replace(/[\s\W-]+/g, '-')
    .replace(/[^a-zA-Z0-9-_]+/g,'');
}

Speichern Sie eine Referenz auf den slugifizierten aktuellen Pfad.

var postRef = ref.child(slugify(window.location.pathname));

Fügen Sie ein Formular hinzu, um neue Kommentare unterhalb der Blog-Beiträge zu posten. Geben Sie die folgende Markierung unterhalb von {{ content }} in `_layouts/post.html` ein.

<h3>Leave a comment</h3>

<form id="comment">
  <label for="message">Message</label>
  <textarea id="message"></textarea>

  <label for="name">Name</label>
  <input type="text" id="name">

  <label for="email">Email</label>
  <input type="text" id="email">

  <input type="submit" value="Post Comment">
</form>

Um die Daten beim Absenden des Formulars an Firebase zu senden, überschreiben Sie den Standard-Submit-Listener in `/js/blog.js`.

$("#comment").submit(function() {
  postRef.push().set({
    name: $("#name").val(),
    message: $("#message").val(),
    md5Email: md5($("#email").val()),
    postedAt: Firebase.ServerValue.TIMESTAMP
  });

  $("input[type=text], textarea").val("");
  return false;
});

postRef.push() erstellt ein Array in Firebase, falls es noch nicht existiert, und gibt eine Referenz auf das erste Element zurück. set speichert die Daten in Firebase.

Wir speichern eine MD5-Prüfsumme der E-Mail-Adresse, um die Privatsphäre der Kommentatoren zu schützen, da die Daten öffentlich sind. Gravatar verwendet MD5s, um Profilbilder anzuzeigen.

Anstelle von new Date().getTime() für den Zeitstempel verwenden wir Firebase.ServerValue.TIMESTAMP. Dies ist ein Zeitstempel von Firebase-Servern, der Zeitzonenprobleme und gefälschte Anfragen vermeidet.

Kommentare anzeigen

Fügen Sie einen Container hinzu, um Kommentare oberhalb des Kommentarformulars in _layouts/post.html zu halten.

<hr>

<div class="comments"></div>

Firebase hat eine Referenz, um auf neue Kommentare zu lauschen. Das Ereignis child_added wird für vorhandene und neue Kommentare ausgelöst. Wir verwenden dasselbe Ereignis, um alle Kommentare zu rendern.

child_added gibt einen aktuellen Snapshot der Daten zurück. Wir erhalten die Daten aus dem Snapshot, formatieren sie in HTML und fügen sie vor <div class="comments"></div> ein.

postRef.on("child_added", function(snapshot) {
      var newPost = snapshot.val();
      $(".comments").prepend('<div class="comment">' +
        '<h4>' + escapeHtml(newPost.name) + '</h4>' +
        '<div class="profile-image"><img src="http://www.gravatar.com/avatar/' + escapeHtml(newPost.md5Email) + '?s=100&d=retro"/></div> ' +
        '' + moment(newPost.postedAt).fromNow() + '<p>' + escapeHtml(newPost.message)  + '</p></div>');
    });

Die vollständige Datei

Speichern Sie die vollständige Datei unter `/js/blog.js`. Ändern Sie <IHRE-APP-ID> in die ID, die Sie zuvor notiert haben.

$(function() {
  var ref = new Firebase("https://comment-jekyll-csstricks.firebaseio.com/"),
    postRef = ref.child(slugify(window.location.pathname));

    postRef.on("child_added", function(snapshot) {
      var newPost = snapshot.val();
      $(".comments").prepend('<div class="comment">' +
        '<h4>' + escapeHtml(newPost.name) + '</h4>' +
        '<div class="profile-image"><img src="http://www.gravatar.com/avatar/' + escapeHtml(newPost.md5Email) + '?s=100&d=retro"/></div> ' +
        '<span class="date">' + moment(newPost.postedAt).fromNow() + '</span><p>' + escapeHtml(newPost.message)  + '</p></div>');
    });

    $("#comment").submit(function() {
      var a = postRef.push();
      
      a.set({
        name: $("#name").val(),
        message: $("#message").val(),
        md5Email: md5($("#email").val()),
        postedAt: Firebase.ServerValue.TIMESTAMP
      });

      $("input[type=text], textarea").val("");
      return false;
    });
});

function slugify(text) {
  return text.toString().toLowerCase().trim()
    .replace(/&/g, '-and-')
    .replace(/[\s\W-]+/g, '-')
    .replace(/[^a-zA-Z0-9-_]+/g,'');
}


function escapeHtml(str) {
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(str));
    return div.innerHTML;
}

Das abgeschlossene kommentarsystem sieht so aus.

Probieren Sie eine funktionierende Demo hier aus. Öffnen Sie zwei Fenster und posten Sie einen Kommentar, Sie werden sehen, wie er sofort in beiden Fenstern erscheint.

Sicherheit

Im Moment kann jeder Kommentare bearbeiten oder löschen. Zur grundlegenden Sicherheit werden wir eine Regel aufstellen, dass Besucher nur Kommentare hinzufügen können. Öffnen Sie in Firebase den Tab **Sicherheit und Regeln**.

Die aktuellen Regeln erlauben globale Lese- und Schreibzugriffe. Um zu verhindern, dass Firebase Daten löscht oder schreibt, falls sie bereits existieren, ändern Sie .write zu.

{
    "rules": {
        ".read": true,
        ".write": "false",
        "$slug": {
          ".write": "!data.exists()",
          "$message": {
            ".write": "!data.exists() && newData.exists()"
          }
        }
    }
}

Ein vollständiger Satz von Authentifizierungsoptionen steht zur Verfügung, um etwas Komplexeres zu erstellen.

Die fertige Seite

Mit ein paar Bibliotheken und 31 Zeilen JavaScript haben wir ein voll funktionsfähiges Backend für Blog-Kommentare auf einer statischen Website.

Damit sind wir am Ende dieser Reihe angelangt. In drei kurzen Tutorials sind wir von einer statischen Seite zu einer aktualisierbaren, live Jekyll-Website mit unserem eigenen kommentarsystem gelangt.

Artikelserie

  1. Eine statische Website in Jekyll konvertieren
  2. Ein Jekyll-CMS mit CloudCannon hinzufügen
  3. Ein kommentarsystem mit Firebase erstellen (Sie sind hier!)